package com.dhcc.bpm.modules.scf.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dhcc.bpm.common.segmentId.LocalCacheIdGenerator;
import com.dhcc.bpm.modules.scf.dto.ScfTruckInfoDTO;
import com.dhcc.bpm.modules.scf.entity.ScfOperationLogInfo;
import com.dhcc.bpm.modules.scf.entity.ScfTruckInfo;
import com.dhcc.bpm.modules.scf.enumUtil.ScfOperationLogInfoEnum;
import com.dhcc.bpm.modules.scf.mapper.ScfTruckInfoMapper;
import com.dhcc.bpm.modules.scf.service.IScfFileAttachmentInfoService;
import com.dhcc.bpm.modules.scf.service.IScfOperationLogInfoService;
import com.dhcc.bpm.modules.scf.service.IScfTruckInfoService;
import com.dhcc.bpm.modules.scf.util.ExcelUtil;
import com.dhcc.bpm.modules.scf.util.OBSUtil;
import com.dhcc.bpm.modules.scf.vo.ScfFileAttachmentInfoVO.ScfFileAttachmentInfoVO;
import com.dhcc.bpm.modules.scf.vo.ScfTruckInfoVO.ScfGetTruckDetailsVO;
import com.dhcc.bpm.modules.scf.vo.ScfTruckInfoVO.ScfGetTruckListVO;
import com.dhcc.bpm.modules.system.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Service
@Slf4j
public class ScfTruckInfoServiceImpl extends ServiceImpl<ScfTruckInfoMapper, ScfTruckInfo> implements IScfTruckInfoService {

    /**
     * 文件附件service接口
     */
    @Autowired
    private IScfFileAttachmentInfoService scfFileAttachmentInfoService;
    /**
     * id生成器
     */
    @Autowired
    private LocalCacheIdGenerator localCacheIdGenerator;
    /**
     * 操作日志接口
     */
    @Autowired
    private IScfOperationLogInfoService scfOperationLogInfoService;
    /**
     * 用户信息service接口
     */
    @Autowired
    private IUserService userService;
    /**
     * obs对象存储工具类
     */
    @Autowired
    private OBSUtil obsUtil;

    /**
     * 查询车辆列表记录
     *
     * @param page
     * @param scfTruckInfo
     * @return
     */
    @Override
    public IPage<ScfGetTruckListVO> selectScfTruckInfoPage(IPage<ScfGetTruckListVO> page, ScfTruckInfoDTO scfTruckInfo) {
        return page.setRecords(baseMapper.selectScfTruckInfoPage(page, scfTruckInfo));
    }

    /**
     * 查询车辆详情
     *
     * @param scfTruckInfo
     * @return
     */
    @Override
    public ScfGetTruckDetailsVO getDetails(ScfTruckInfoDTO scfTruckInfo) {
        ScfGetTruckDetailsVO detail = baseMapper.getDetails(scfTruckInfo.getRowId());
        if (detail != null) {
            // 获取与文件附件表关联的id
            String rowId = detail.getRowId();
            // 查询关联的附件信息
            List<ScfFileAttachmentInfoVO> scfFileAttachmentInfoVOS = scfFileAttachmentInfoService.selectAllByAssociationId(rowId);
            if (scfFileAttachmentInfoVOS != null) {
                // 将附件信息存进dto里
                detail.setFileAttachmentInfoVOS(scfFileAttachmentInfoVOS);
            }
        }
        return detail;
    }

    /**
     * 新增车辆信息
     *
     * @param scfTruckInfo
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveTruck(ScfTruckInfoDTO scfTruckInfo) throws Exception {
        // 录入开始首先判断车辆是否已录入，如果已录入则抛出异常并提示
        if (baseMapper.selectRowIdByTruckNum(scfTruckInfo.getTruckNum(),scfTruckInfo.getOrgCode()) != null) {
            throw new Exception("车辆:" + scfTruckInfo.getTruckNum() + "已录入，请勿重新录入！");
        }
        // 生成日期
        SimpleDateFormat date = new SimpleDateFormat("YYYYMMdd");
        String formatdate = date.format(new Date());
        // 生成时间
        SimpleDateFormat timeFormat = new SimpleDateFormat("HHmmss");
        String formTime = timeFormat.format(new Date());
        // 生成ROW_ID
        String rowId = "CL" + localCacheIdGenerator.nextId() + formTime;
        // 开始补充对象字段start
        if (scfTruckInfo.getLoadCapacity() == null) {
            // 核定载重量未填写则默认填充为0
            scfTruckInfo.setLoadCapacity(BigDecimal.valueOf(0));
        }
        // 设置记录编号
        scfTruckInfo.setRowId(rowId);
        // 设置登记日期
        scfTruckInfo.setRecordDate(formatdate);
        // 设置登记时间
        scfTruckInfo.setRecordTime(formTime);
        // 补充对象字段结束end
        List<String> rowIds = scfTruckInfo.getRowIds();
        boolean isSave = save(scfTruckInfo);
        // 设置车辆相关文件存放路径
        String path = "CL" + "/" + rowId + "/";
        if (rowIds != null) {
            if (!rowIds.isEmpty()) {
                if (isSave) {
                    for (String fileRowId : rowIds) {
                        // 根据文件id获取文件的临时objectKey
                        String objectKeyOfTemp = scfFileAttachmentInfoService.getFilePath(fileRowId,null);
                        // 截取文件的名称
                        String extractFileName = obsUtil.extractFileName(objectKeyOfTemp);
                        // 拼接正式的objectKey
                        String objectKey = path + extractFileName;
                        // 将附件文件从临时目录转移至正式目录中
                        obsUtil.copyFile(objectKey, objectKeyOfTemp);
                        scfFileAttachmentInfoService.updateFilePath(fileRowId, objectKey);
                    }
                }
                scfFileAttachmentInfoService.batchUpdateField(rowIds, rowId);
            }
        }
        // 生成日期时间
        SimpleDateFormat datetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDateTime = datetime.format(new Date());
        ScfOperationLogInfo scfOperationLogInfo = new ScfOperationLogInfo();
        scfOperationLogInfo.setRowId("Log" + formatdate + formTime + localCacheIdGenerator.nextId());
        // 根据用户id查询用户名称，重新赋值登记人字段
        List<Long> ids = new ArrayList<>();
        ids.add(Long.valueOf(scfTruckInfo.getRecorder()));
        scfOperationLogInfo.setRecorder(userService.selectUserNameByIds(ids).get(0));
        scfOperationLogInfo.setOperationModule(ScfOperationLogInfoEnum.SUBJECT.getOperation());
        scfOperationLogInfo.setOperationFunction("车辆信息维护");
        scfOperationLogInfo.setOperationType(ScfOperationLogInfoEnum.ADD.getOperation());
        scfOperationLogInfo.setOperationContent("新增一条车辆信息，车牌号：" + scfTruckInfo.getTruckNum());
        scfOperationLogInfo.setRecordDate(formattedDateTime);
        // 判断车辆信息是否录入
        if (isSave) {
            // 如果已录入则记录操作日志
            scfOperationLogInfoService.saveOperationLogInfo(scfOperationLogInfo);
        }
        return isSave;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int bachSaveTruck(List<ScfTruckInfo> scfTruckInfos, String operatorId) {
        List<ScfTruckInfo> scfTruckInfoList = new ArrayList<>();
        List<ScfOperationLogInfo> scfOperationLogInfoList = new ArrayList<>();
        for (ScfTruckInfo scfTruckInfo : scfTruckInfos) {
            // 设置登记人ID
            scfTruckInfo.setRecorder(operatorId);
            // 车牌颜色
            String truckColourNum = scfTruckInfo.getTruckColourNum();
            if (truckColourNum != null) {
                switch (truckColourNum) {
                    case "黄色":
                        // 执行与 value1 匹配的代码块
                        scfTruckInfo.setTruckColourNum("7002");
                        break;
                    case "蓝色":
                        // 执行与 value2 匹配的代码块
                        scfTruckInfo.setTruckColourNum("7003");
                        break;
                    case "黄绿色":
                        // 执行与 value2 匹配的代码块
                        scfTruckInfo.setTruckColourNum("7001");
                        break;
                    // 可以有更多的 case 分支
                    default:
                        // 如果没有任何 case 匹配，则执行 default 代码块
                        break;
                }
            }

            // 使用性质
            String use = scfTruckInfo.getUse();
            if (use != null) {
                switch (use) {
                    case "货运":
                        // 执行与 value1 匹配的代码块
                        scfTruckInfo.setUse("1");
                        break;
                    // 可以有更多的 case 分支
                    default:
                        // 如果没有任何 case 匹配，则执行 default 代码块
                        break;
                }
            }
            // 生成日期
            SimpleDateFormat date = new SimpleDateFormat("YYYYMMdd");
            String formatdate = date.format(new Date());
            // 生成时间
            SimpleDateFormat timeFormat = new SimpleDateFormat("HHmmss");
            String formTime = timeFormat.format(new Date());
            // 生成ROW_ID
            String rowId = "CL" + localCacheIdGenerator.nextId() + formTime;
            // 开始补充对象字段start
            if (scfTruckInfo.getLoadCapacity() == null) {
                // 核定载重量未填写则默认填充为0
                scfTruckInfo.setLoadCapacity(BigDecimal.valueOf(0));
            }
            // 设置记录编号
            scfTruckInfo.setRowId(rowId);
            // 设置登记日期
            scfTruckInfo.setRecordDate(formatdate);
            // 设置登记时间
            scfTruckInfo.setRecordTime(formTime);
            // 补充对象字段结束end
            // 录入开始首先判断车辆是否已录入，如果已录入则抛出异常并提示
            if (baseMapper.selectRowIdByTruckNum(scfTruckInfo.getTruckNum() ,scfTruckInfo.getOrgCode()) == null) {
                scfTruckInfoList.add(scfTruckInfo);
                // 生成日期时间
                SimpleDateFormat datetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String formattedDateTime = datetime.format(new Date());
                ScfOperationLogInfo scfOperationLogInfo = new ScfOperationLogInfo();
                scfOperationLogInfo.setRowId("Log" + formatdate + formTime + localCacheIdGenerator.nextId());
                // 根据用户id查询用户名称，重新赋值登记人字段
                List<Long> ids = new ArrayList<>();
                ids.add(Long.valueOf(scfTruckInfo.getRecorder()));
                scfOperationLogInfo.setRecorder(userService.selectUserNameByIds(ids).get(0));
                scfOperationLogInfo.setOperationModule(ScfOperationLogInfoEnum.SUBJECT.getOperation());
                scfOperationLogInfo.setOperationFunction("车辆信息维护");
                scfOperationLogInfo.setOperationType(ScfOperationLogInfoEnum.ADD.getOperation());
                scfOperationLogInfo.setOperationContent("新增一条车辆信息，车牌号：" + scfTruckInfo.getTruckNum());
                scfOperationLogInfo.setRecordDate(formattedDateTime);
                scfOperationLogInfoList.add(scfOperationLogInfo);
            }
        }
        boolean saveBatch = saveBatch(scfTruckInfoList);
        if (saveBatch) {
            scfOperationLogInfoService.bachSaveOperationLogInfo(scfOperationLogInfoList);
        }
        return scfTruckInfoList.size();
    }

    /**
     * 更新车辆信息
     *
     * @param scfTruckInfo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateTruck(ScfTruckInfoDTO scfTruckInfo) {
        String rowId = scfTruckInfo.getRowId();
        List<String> rowIds = scfTruckInfo.getRowIds();
        // 设置车辆相关附件存放路径
        String path = "CL" + "/" + rowId + "/";
        if (rowId != null) {
            if (!rowIds.isEmpty()) {
                // 取消旧文件与记录关联
                scfFileAttachmentInfoService.updataFiledNull(rowId);
                // 给上传的新文件添加关联编号
                scfFileAttachmentInfoService.batchUpdateField(rowIds, rowId);
                for (String fileRowId : rowIds) {
                    // 根据文件id获取文件的临时objectKey
                    String objectKeyOfTemp = scfFileAttachmentInfoService.getFilePath(fileRowId,null);
                    // 截取文件的名称
                    String extractFileName = obsUtil.extractFileName(objectKeyOfTemp);
                    // 拼接正式的objectKey
                    String objectKey = path + extractFileName;
                    // 将新上传的附件文件从临时目录转移至正式目录下
                    obsUtil.copyFile(objectKey, objectKeyOfTemp);
                    scfFileAttachmentInfoService.updateFilePath(fileRowId, objectKey);
                }
            }
        }
        boolean update = updateById(scfTruckInfo);
        // 生成日期
        SimpleDateFormat date = new SimpleDateFormat("YYYYMMdd");
        String formatdate = date.format(new Date());
        // 生成时间
        SimpleDateFormat timeFormat = new SimpleDateFormat("HHmmss");
        String formTime = timeFormat.format(new Date());
        // 生成日期时间
        SimpleDateFormat datetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDateTime = datetime.format(new Date());
        ScfOperationLogInfo scfOperationLogInfo = new ScfOperationLogInfo();
        scfOperationLogInfo.setRowId("Log" + formatdate + formTime + localCacheIdGenerator.nextId());
        // 根据用户id查询用户名称，重新赋值登记人字段
        List<Long> ids = new ArrayList<>();
        ids.add(Long.valueOf(scfTruckInfo.getRecorder()));
        scfOperationLogInfo.setRecorder(userService.selectUserNameByIds(ids).get(0));
        scfOperationLogInfo.setOperationModule(ScfOperationLogInfoEnum.SUBJECT.getOperation());
        scfOperationLogInfo.setOperationFunction("车辆信息维护");
        scfOperationLogInfo.setOperationType(ScfOperationLogInfoEnum.UPDATE.getOperation());
        scfOperationLogInfo.setOperationContent("更新一条车辆信息，车牌号：" + scfTruckInfo.getTruckNum());
        scfOperationLogInfo.setRecordDate(formattedDateTime);
        // 判断车辆记录更新是否成功
        if (update) {
            // 更新如果成功则记录操作日志
            scfOperationLogInfoService.saveOperationLogInfo(scfOperationLogInfo);
        }
        return update;
    }

    /**
     * 车辆信息批量导入接口
     *
     * @param operatorId
     * @param file
     * @return
     * @throws IOException
     */
    @Override
    public List<ScfTruckInfo> batchSaveScfTruckInfo(String operatorId, MultipartFile file) throws IOException {
        // 获取文件的Base64编码
        byte[] fileBytes = file.getBytes();
        // 解析excel文件获取数据集合
        List<ScfTruckInfo> scfTruckInfos = ExcelUtil.readExcel(fileBytes, ScfTruckInfo.class, "车辆信息", 3);
        log.info("数据集合为：{}", scfTruckInfos);
        return scfTruckInfos;
    }

    @Override
    public Boolean deleteByIds(String[] ids) {
        // 删除车辆信息
        // 删除
        return this.baseMapper.deleteByIds(ids);
    }
}
